package com.example.springboot.config;

import cn.hutool.json.JSONUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class JwtTokenUtil {

    @Value("${jwt.secret-key:default-secret-key}")
    private String secretKey;

    @Value("${jwt.expiration-time:86400000}")
    private long expirationTime; // 1 天，单位：毫秒

    private Algorithm algorithm;
    private JWTVerifier verifier;

    @PostConstruct
    public void init() {
        if ("default-secret-key".equals(secretKey)) {
            System.out.println("警告: 使用默认密钥，禁止在生产环境中使用！");
        }
        this.algorithm = Algorithm.HMAC256(secretKey);
        this.verifier = JWT.require(algorithm).build();
    }

    // 原有方法：生成 Token（不改变）
    public String generateToken(String username, String role) {
        Map<String, Object> header = new HashMap<>();
        header.put("Type", "JWT");
        header.put("alg", "HS256");

        Date expiryDate = new Date(System.currentTimeMillis() + expirationTime);

        Map<String, String> payload = new HashMap<>();
        payload.put("id", username); // username 存储在 id 中
        payload.put("role", role);

        return JWT.create()
                .withHeader(header)
                .withClaim("userid", JSONUtil.toJsonStr(payload))
                .withIssuedAt(new Date())
                .withExpiresAt(expiryDate)
                .sign(algorithm);
    }

    // 新增重载方法：支持 realUserId
    public String generateToken(String username, String role, String realUserId) {
        Map<String, Object> header = new HashMap<>();
        header.put("Type", "JWT");
        header.put("alg", "HS256");

        Date expiryDate = new Date(System.currentTimeMillis() + expirationTime);

        Map<String, String> payload = new HashMap<>();
        payload.put("id", username); // username 存储在 id 中
        payload.put("role", role);
        payload.put("realUserId", realUserId); // 新增 realUserId 字段

        return JWT.create()
                .withHeader(header)
                .withClaim("userid", JSONUtil.toJsonStr(payload))
                .withIssuedAt(new Date())
                .withExpiresAt(expiryDate)
                .sign(algorithm);
    }

    // 验证 Token 是否有效
    public boolean validateToken(String token) {
        try {
            verifier.verify(token);
            return true;
        } catch (JWTVerificationException e) {
            return false;
        }
    }

    // 从 Token 中获取用户名
    public String getUsernameFromToken(String token) {
        try {
            DecodedJWT jwt = verifier.verify(token);
            String userid = jwt.getClaim("userid").asString();
            return JSONUtil.parseObj(userid).getStr("id");
        } catch (Exception e) {
            return null;
        }
    }

    // 从 Token 中获取角色
    public String getRoleFromToken(String token) {
        try {
            DecodedJWT jwt = verifier.verify(token);
            String userid = jwt.getClaim("userid").asString();
            return JSONUtil.parseObj(userid).getStr("role");
        } catch (Exception e) {
            return null;
        }
    }

    // 新增方法：从 Token 中获取真实的 userId
    public String getRealUserIdFromToken(String token) {
        try {
            DecodedJWT jwt = verifier.verify(token);
            String userid = jwt.getClaim("userid").asString();
            String realUserId = JSONUtil.parseObj(userid).getStr("realUserId");
            System.out.println("Extracted RealUserId: " + realUserId); // 调试日志
            if (realUserId == null) {
                // 如果 token 中没有 realUserId，返回 null 或抛出异常，取决于业务需求
                System.out.println("No realUserId found in token, falling back to username as userId");
                return getUsernameFromToken(token); // 兼容旧 token
            }
            return realUserId;
        } catch (Exception e) {
            System.err.println("Failed to extract realUserId: " + e.getMessage());
            return null;
        }
    }

    // 检查 Token 是否过期
    public boolean isTokenExpired(String token) {
        try {
            DecodedJWT jwt = verifier.verify(token);
            Date expiresAt = jwt.getExpiresAt();
            return expiresAt.before(new Date());
        } catch (Exception e) {
            return true; // 如果解析失败，视为过期
        }
    }

    // 获取 Token 的剩余有效时间（单位：秒）
    public long getRemainingTime(String token) {
        try {
            DecodedJWT jwt = verifier.verify(token);
            Date expiresAt = jwt.getExpiresAt();
            long now = System.currentTimeMillis();
            long expires = expiresAt.getTime();
            return (expires - now) / 1000; // 返回秒数
        } catch (Exception e) {
            return -1; // 无效 Token 返回 -1
        }
    }
}